package com.evola.audit.util {
	import com.evola.audit.Audit;
	import com.evola.audit.model.AuditDay;
	import com.evola.audit.model.AuditItem;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.collections.Sort;
	import mx.collections.SortField;

	public class AuditUtil {

		/**
		 * Metoda pretvara kolekciju AuditDataObject objekata
		 * u kolekciju grupisanih AuditDay objekata sa odgovarajucom
		 * listom AuditItem objekata. Pre grupisanja metoda sortira
		 * sve AuditDataObject objekte po datumu u opadajucem redosledu.
		 * @param value
		 * @return
		 *
		 */
		public static function convertAuditData(value : ArrayCollection, maxNumOfAudits : int) : ArrayCollection {

			var auditDays : ArrayCollection = new ArrayCollection();

			if (value) {

				//first we sort audits in descending order in relation to date
				sort(value);
				//now, after sorting, we truncate the collection to the limited sizes
				limit(value, maxNumOfAudits);

				var auditItem : AuditItem;

				for each (var ao : AuditDataObject in value) {

					var currentAuditDay : AuditDay;

					if (ao.isInDays(auditDays)) {

						currentAuditDay = auditDays.getItemAt(auditDays.length - 1) as AuditDay;
					} else {
						currentAuditDay = new AuditDay();
						currentAuditDay.date = ao.time;

						auditDays.addItem(currentAuditDay);
					}

					auditItem = new AuditItem(ao);

					currentAuditDay.items.addItem(auditItem);
				}
			}

			return auditDays;
		}

		/**
		 * Method removes the excess items from the auditDataObject collection. 
		 * @param auditDataObjects
		 * @param maxNumOfAudits
		 * 
		 */		
		private static function limit(auditDataObjects : ArrayCollection, maxNumOfAudits : int) : void {

			if (auditDataObjects) {

				while (auditDataObjects.length > maxNumOfAudits) {

					auditDataObjects.removeItemAt(auditDataObjects.length - 1);
				}
			}
		}

		private static function sort(dp : ArrayCollection) : void {

			/* Create the SortField object for the "data" field in the ArrayCollection object, and make sure we do a numeric sort. */
			var dataSortField : SortField = new SortField();
			dataSortField.name = "time";
			dataSortField.descending = true;

			/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
			var numericDataSort : Sort = new Sort();
			numericDataSort.fields = [dataSortField];

			/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
			dp.sort = numericDataSort;
			dp.refresh();
		}
		
		public static function createActionDataProvider(dataProvider : ICollectionView, audit : Audit) : Array {
			
			return createSpecificDataprovider(dataProvider, "action", audit);
		}
		
		public static function createAuthorDataProvider(dataProvider : ICollectionView, audit : Audit) : Array {
			
			return createSpecificDataprovider(dataProvider, "authorName", audit);
		}
		
		public static function createObjectDataProvider(dataProvider : ICollectionView, audit : Audit) : Array {
			
			return createSpecificDataprovider(dataProvider, "object", audit);
		}
		
		public static function createObjectIdDataProvider(dataProvider : ICollectionView, audit : Audit) : Array {
			
			return createSpecificDataprovider(dataProvider, "objectId", audit);
		}
		
		private static function createSpecificDataprovider(dataProvider : ICollectionView, attribute : String, audit : Audit) : Array {
			
			var arr : Array = new Array();
			
			if (dataProvider) {
				
				for each (var auditDay : AuditDay in dataProvider) {
					
					var cs : IViewCursor = auditDay.items.createCursor();
					
					while (cs.current) {
						
						var attributeValue : String = (cs.current as AuditItem)[attribute];
						
						if (arr.indexOf(attributeValue) == -1)
							arr.push(attributeValue);
						
						cs.moveNext();
					}
				}
			}
			
			arr.sort(Array.CASEINSENSITIVE);
			
			//sada dodajemo prazan element
			arr.splice(0, 0, audit.allString);
			
			return arr;
		}
	}
}
